package com.interview.service.utils;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.io.IOException;
import java.util.*;


//不要想着 使用 * ~ ...这些通配 其实没什么卵用 分词器都给你分词好了 直接使用  :  就行了
//如果涉及到 区间的话 可以使用 []
//比如  name:[* TO 100]  查询name小于等于100   name:[100 TO *] 查询name值大于等于100
//我们也可以用来 查询时间段或者价格区间      name:[ 时间1 TO 时间2]   查询name里时间是 时间1 到 时间2之间的数据
//注意 liunx 要慢8小时

@Repository("Springboot_SolrUtils")
public class Springboot_SolrUtils {

    @Autowired
    private SolrClient server;

  

    /**
     * 查询全部  返回的是json   [{},{},{}]   用的时候转为map就行了
     *
     */
    public  List<Map<String,String>> soleAll() {
        List<Map<String,String>> list=new ArrayList<>();
        SolrQuery query = new SolrQuery("*:*");
        QueryResponse resp = null;
        try {
            resp = server.query(query);
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
        }
        SolrDocumentList results = resp.getResults();

        for (int i = 0; i <results.size()  ; i++) {
            Map<String,String> map=new HashMap<>();
            for (Map.Entry<String, Object> entry : resp.getResults().get(i).entrySet()) {
                String s = entry.getValue().toString();
                map.put(entry.getKey(),s.substring(1,s.length()-1));

            }
            list.add(map);
        }
        return list;
    }

    // soleAll() 演示
    @Test
    public void soleAll0_test(){
        List<Map<String, String>> list = soleAll();
        System.out.println(list);
    }

    // 查询所有指定字段 所匹配的值   满足条件的  所有内容    (也可以称为关键字  我们使用的是ik分词器)
    public  List<Map<String,String>> soleAll(String name,String keyword) {
        List<Map<String,String>> list=new ArrayList<>();
        SolrQuery query = new SolrQuery(name+":"+keyword);
        QueryResponse resp = null;
        try {
            resp = server.query(query);
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
        }
        SolrDocumentList results = resp.getResults();

        for (int i = 0; i <results.size()  ; i++) {
            Map<String,String> map=new HashMap<>();
            for (Map.Entry<String, Object> entry : resp.getResults().get(i).entrySet()) {
                String s = entry.getValue().toString();
                map.put(entry.getKey(),s.substring(1,s.length()-1));
            }
            list.add(map);
        }

        return list;
    }

    // soleAll() 演示
    @Test
    public void soleAll1_test(){
        List<Map<String, String>> list = soleAll("blogTitle","龙头");
        System.out.println("数量"+list.size());
        System.out.println(list);
    }





    // 查询所有指定字段的值
    public  List<String> soleFieldAll(String name){
        List<String> list=new ArrayList<>();
        SolrQuery query = new SolrQuery(name+":*");  //查询全部内容
        QueryResponse resp = null;
        try {
            resp = server.query(query);
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
        }
        SolrDocumentList documents =  resp.getResults();
//     获取指定字段 内容
        for (SolrDocument doc : documents) {
            String s = doc.get(name).toString();
            list.add(s.substring(1,s.length()-1));
        }

        return list;
    }

    // soleAll(String name) 演示
    @Test
    public void soleFieldAll0_test(){
        List<String> list = soleFieldAll("blogTitle");
        System.out.println(list);
    }


    // 查询所有指定字段 的 匹配值   (也可以称为关键字 我们使用的是ik分词器)
    public  List<String> soleFieldAll(String name,String keyword){
        List<String> list=new ArrayList<>();
        SolrQuery query = new SolrQuery(name+":"+keyword);  //查询全部内容
        QueryResponse resp = null;
        try {
            resp = server.query(query);
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
        }
        SolrDocumentList documents =  resp.getResults();
//     获取指定字段 内容
        for (SolrDocument doc : documents) {
            String s = doc.get(name).toString();
            list.add(s.substring(1,s.length()-1));
        }

        return list;
    }
    // soleAll(String name) 演示
    @Test
    public void soleFieldAll1_test(){
        List<String> list = soleFieldAll("blogTitle","龙头");
        System.out.println(list);
    }



    // 查询高亮

    /**
     *
     * @param name 查询的字段
     * @param keyword  查询的条件
     *              ----------分页
     * @param  start 开始
     * @param rows  结束
     *              ----------排序
     * @param sort  按照什么字段进行排序查询
     *              ----------需要显示高亮的字段
     *
     * @param fields  查询成功后 需要进行高亮的字段
     *
     *
     */
    public   List<Map<String, String>> soleHighlighting(String name ,String keyword,int start,int rows,String sort,String... fields){
        SolrQuery query = new SolrQuery();
        // 设置查询条件
        query.setQuery(name+":"+ keyword);
        // 设置分页信息
        query.setStart( start);  //开始
        query.setRows(rows);  //结束
        // 按照blogId字段进行排序查询
        query.setSort(sort, SolrQuery.ORDER.desc);   //desc降序    asc升序
        List<String> lista=new ArrayList<>(Arrays.asList(fields));
        boolean id = lista.contains("id");

        if (!id){
            lista.add("id");
        }
        // 只查询显示哪些字段
        StringBuilder stringBuilder=new  StringBuilder();
        for (String field : lista) {
            stringBuilder.append(field+",");
        }
        query.setFields(stringBuilder.toString().substring(0,stringBuilder.length()-1).split(","));
        // 设置高亮信息
        query.setHighlight(true);
        for (String field : fields) {
            query.addHighlightField(field );//设置高亮字段
        }

        query.setHighlightSimplePre("<font  color='red'>"); //设置高亮的前缀
        query.setHighlightSimplePost("</font>"); //设置高亮的后缀
        // 执行查询
        QueryResponse response = null;
        try {
            response = server.query(query);
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
        }
        // 获取doc文档
        SolrDocumentList documents = response.getResults();
        // 获取高亮显示信息
        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
        List<Map<String, String>> list=new ArrayList<>();
//     获取指定字段高亮后的内容
        for (SolrDocument doc : documents) {
            LinkedHashMap<String,String> map=new LinkedHashMap<>();//保证顺序
            for (String field : fields) {
                List<String> hightDocs = highlighting.get(doc.get("id")).get(field );
                if (hightDocs != null){
                    map.put(field,hightDocs.get(0));
                } else {
                    if(doc.get(field)!=null){
                        String s = doc.get(field).toString();
                        map.put(field, s.substring(1, s.length()-1));
                    }
                }

            }

            list.add(map);


        }

        return  list;
    }

    @Test
    public void soleHighlighting_test(){


        //需要显示的字段
        String[] fields={"blogContent", "blogTitle","blogId"};

        List<Map<String, String>> list = soleHighlighting("blogTitle", "龙头", 0, 50, "blogId",  fields);

        System.out.println(list );


    }




    // 删除全部数据

    public  void  deleteDocumentAll(){
        //删除所有的索引
        try {
            server.deleteByQuery("*:*");
            //提交修改
            server.commit();

        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
        }

    }


    @Test
    public void deleteDocument_test1() throws Exception {
        deleteDocumentAll();
    }

    //    按照 字段匹配 删除
    public  void  deleteDocument(String id){
        //删除所有的索引
        try {
            server.deleteById(id);  //删除指定 id 的文档
            //提交修改
            server.commit();
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
        }

    }


    @Test
    public void deleteDocument_test2() throws Exception {
        deleteDocument("977-2021aZ1oE7nS10vR52dV25u816Q-96");
    }
    //删除指定字段 的所有匹配数据
    public  void  deleteDocument(String name,String keyword){

        try {
            server.deleteByQuery(name+":"+ keyword);
            //提交修改
            server.commit();
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
        }

    }



    @Test
    public void deleteDocument_test3() throws Exception {
        deleteDocument("time","[2021-01-07 TO 2021-01-30]");
    }






    //添加数据
    /**
     * 添加   id是唯一的  但是 如果你实体类中没有指定id   那么solr 会自动给你分配 比如:91dc8523-324c-4fa1-944d-fb7e100da857
     * 我说的id是名称完全一样  id=id
     */

    public void soleAdd(Object object){
        try {

            server.addBean(object);
            UpdateResponse updateResponse = server.commit();//提交请求
            if (updateResponse.getStatus()!=0){
                throw new Exception("添加失败");
            }      //返回0 添加成功

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void solrAdd_test(){
        // 实体类
//        BlogCore blog = new BlogCore();
//        blog.setBlogId("9");
//        blog.setBlogTitle("超越业x龙xxx头xxx");
//        blog.setBlogContent("达摩院一定也必须要超越英特尔，必须超越微软，必须超越IBM，因为我们生于二十一世纪，我们是有机会后发优势的1。");
//        blog.setCreateTime(new Date());
//
//        soleAdd(blog);
    }






    //多线程 并发测试
    public  void main(String[] args) {

        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {

                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //需要显示的字段
                    String[] fields={"blogContent", "blogTitle","blogId"};

                    List<Map<String, String>> list = soleHighlighting("blogTitle", "龙头", 0, 50, "blogId",  fields);

                    System.out.println(list );
                }
            }).start();
        }
    }


}
